// Copyright 2019 orivil.com. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found at https://mit-license.org.

package utils

import (
	"encoding/json"
	"errors"
	"fmt"
	"gitee.com/tugoer/psys/env"
	"io/ioutil"
	"net/http"
	"net/url"
	"regexp"
)

//type gameInfo struct {
//	Data string `json:"data"`
//	IV string `json:"iv"`
//}

//var ivReg = regexp.MustCompile(`"iv":\s*"([\s\S]*?)"`)
//var dataReg = regexp.MustCompile(`"data":\s*"([\s\S]*?)",`)
var infoReg = regexp.MustCompile(`var gameInfo\s*=\s*([\s\S]*?);`)

//var dataReg = regexp.MustCompile("data:\\s*'([\\s\\S]*?)'")

//var dataReg = regexp.MustCompile("var gameData\\s*=\\s+([\\s\\S]+?);\\s")

var headImgReg = regexp.MustCompile("headimg_config:\\s*'([\\s\\S]*?)',")

var nameReg = regexp.MustCompile("draw_config:\\s*'([\\s\\S]*?)',")

var specialReg = regexp.MustCompile("result_image:\\s*'([\\s\\S]*?)',")

type GameData struct {
	Data        []byte
	HeadImgCfg  []byte
	NameCfg     []byte
	SpecialData []byte
}

func GetGameData(id string) (*GameData, error) {
	URL := env.Env.GameUrl(id)
	resp, err := http.Get(URL)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var data []byte
	data, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	info := find(infoReg, data)
	if len(info) == 0 {
		return nil, fmt.Errorf("can not find game info: %s", infoReg.String())
	}
	gameInfo := map[string]string{}
	err = json.Unmarshal(info, &gameInfo)
	if err != nil {
		return nil, fmt.Errorf("unmarshal game info: %s", err)
	}
	dt := gameInfo["data"]
	if len(dt) == 0 {
		return nil, fmt.Errorf("can not find game data")
	}
	iv := gameInfo["iv"]
	if len(iv) == 0 {
		return nil, fmt.Errorf("can not find iv")
	}
	var gameData []byte
	gameData, err = env.Env.Decode([]byte(iv), dt)
	if err != nil {
		return nil, fmt.Errorf("decode game data got error: %s", err)
	}
	headImgCfg := find(headImgReg, data)
	nameCfg := find(nameReg, data)
	specialData := find(specialReg, data)
	return &GameData{
		Data:        gameData,
		HeadImgCfg:  headImgCfg,
		NameCfg:     nameCfg,
		SpecialData: specialData,
	}, nil
}

func find(reg *regexp.Regexp, data []byte) []byte {
	subs := reg.FindSubmatch(data)
	if len(subs) > 0 {
		return subs[len(subs)-1]
	}
	return nil
}

func GetGameResult(id, option, acid, ext string) (data []byte, err error) {
	resp, err := http.PostForm(env.Env.GetResultUrl(), url.Values{
		"id":     []string{id},
		"option": []string{option},
		"acid":   []string{acid},
		"ext":    []string{ext},
	})
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	return ioutil.ReadAll(resp.Body)
}

type Order string

const (
	UTime Order = "utime"
	View  Order = "view"
)

func GetSubjects(page string, order Order) (data []byte, err error) {
	var URL string
	switch order {
	case UTime:
		URL = env.Env.UTimeSubjectUrl(page)
	case View:
		URL = env.Env.HotSubjectUrl(page)
	default:
		return nil, errors.New("不允许的排序规则: " + string(order))
	}
	resp, err := http.Get(URL)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	return ioutil.ReadAll(resp.Body)
}
